using System;
using System.Collections.Generic;
using AutoMapper;
using Tools.Domain.Common.Repositories.Contracts;
using Web.App.Infrastructure.ObjectStore.Contracts;
using Webshop20.Application.DataTransferObjects;
using Webshop20.Application.Queries.Messages;
using Webshop20.Domain.Catalog.Core;
using Webshop20.Domain.Shared.Products.Core;

namespace Webshop20.Application.Queries.Services
{
    public class GetCartService : IGetCartService
    {
        private readonly IObjectStoreRepository objectStoreRepository;
        private readonly IRepository<Visitor> vistorRepository;
        private readonly ISalesTax salesTax;

        public GetCartService(IObjectStoreRepository objectStoreRepository, ISalesTax salesTax, IRepository<Visitor> vistorRepository)
        {
            this.objectStoreRepository = objectStoreRepository;
            this.vistorRepository = vistorRepository;
            this.salesTax = salesTax;
        }

        public ISystemMessage Handle(ISystemMessage request)
        {
            var cartServiceRequest = (GetCartRequest)request;
            Visitor visitor;

            if (cartServiceRequest.VisitorId != null)
                visitor = vistorRepository.FindById(cartServiceRequest.VisitorId);
            else
                visitor = (Visitor) objectStoreRepository.Find((Guid) cartServiceRequest.VisitorInterimKey).Data;
            
            var cartResponse = new GetCartResponse(ConvertCartItemsToDTOs(visitor.Cart.CartItems, cartServiceRequest.Date), ConvertCartItemsToDTOs(visitor.Cart.CartItems, cartServiceRequest.Date), visitor.Cart.CalculateTotal(salesTax, cartServiceRequest.Date));
            
            return cartResponse;
        }

        private IEnumerable<CartItemDTO> ConvertCartItemsToDTOs(IEnumerable<ShoppingCartItem> items, DateTime calculationDate)
        {
            foreach (var cartItem in items)
            {
                var cartItemDTO = (CartItemDTO)Mapper.Map(cartItem, typeof (ShoppingCartItem), typeof (CartItemDTO));
                cartItemDTO.ProductPrice = cartItem.Calculate(salesTax, calculationDate);
                yield return cartItemDTO;
            }
        }

    }

    public interface IGetCartService : IService{}
}